package com.cloudfast.platform.user.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloudfast.common.date.DateUtils;
import com.cloudfast.common.encode.EncodeUtils;
import com.cloudfast.common.page.Page;
import com.cloudfast.common.user.LoginUser;
import com.cloudfast.common.user.UserUtils;
import com.cloudfast.platform.org.entity.Org;
import com.cloudfast.platform.org.service.OrgService;
import com.cloudfast.platform.role.service.RoleService;
import com.cloudfast.platform.user.dao.UserDao;
import com.cloudfast.platform.user.entity.User;

/**
 * @author liuyw
 * @描述:用户管理
 * @date 2020年4月10日
 */
@Service
@Transactional(readOnly = true)
public class UserService {
    protected static final Logger logger = LoggerFactory.getLogger(Logger.class);

    @Autowired
    private UserDao userDao;

    @Autowired
    private OrgService orgService;

    @Autowired
    private RoleService roleService;

    @Transactional(readOnly = false)
    public void save(User entity) {
        boolean isAddDefaultRole = false;

        try {

            if (StringUtils.isEmpty(entity.getPassword())) {
                entity.setPassword(EncodeUtils.encode(entity.getUsername().substring(0, 1).toUpperCase()
                        + entity.getUsername().substring(1, entity.getUsername().length()) + "@"
                        + DateUtils.getDate("yyyy")));
            }
            if (entity.getId() == null && !"admin".equals(entity.getUsername())) {
                isAddDefaultRole = true;
            }

            if (StringUtils.isEmpty(entity.getOrgId() + "")) {
                Org org = orgService.findTopOrg();
                entity.setOrgId(org.getId());
            }
            userDao.saveOrUpdate(entity);
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            if (isAddDefaultRole) {
                this.roleService.addUser(2L, entity.getId());
            }
        }
    }

    /**
     * @param id
     * @return
     * @描述:根据id查询用户
     * @author liuyw
     * @date 2020年4月18日
     */
    public User findOne(Long id) {
        try {
            return userDao.findOne(id);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return null;
    }

    @Transactional(readOnly = false)
    public void delete(Long id) {
        userDao.deleteById(id);
    }

    public List<User> findList() {
        userDao.findList("from User");
        return userDao.findAll();
    }

    /**
     * @param id
     * @param username
     * @return
     * @描述:检查用户名是否存在
     * @author liuyw
     * @date 2020年4月20日
     */
    public int checkUsername(Long id, String username) {
        StringBuilder sql = new StringBuilder("from User where 1=1 and username=:username ");
        Map<String, Object> params = new HashMap<>(2);
        params.put("username", username);
        if (id != null && id > 0) {
            sql.append(" and id!=:id");
            params.put("id", id);
        }
        List<User> list = userDao.findList(sql.toString(), params);
        if (list != null && !list.isEmpty()) {
            return list.size();
        }
        return 0;
    }

    /**
     * @param id
     * @param password @
     * @描述:修改密码
     * @author liuyw
     * @date 2020年4月20日
     */
    @Transactional(readOnly = false)
    public void saveNewPw(Long id, String password) {
        userDao.updateUserPassword(id, password);
    }


    /**
     * 拼接的sql
     *
     * @param entity
     * @param params
     * @return
     */
    private String findHQL(User entity, Map<String, Object> params) {
        StringBuilder ql = new StringBuilder(
                "select u from User u,RegionCity region,UserRole ur,Role r where 1=1 and u.regionCode=region.regionCode and u.id=ur.userId and r.id=ur.roleId ");
        if (StringUtils.isNotEmpty(entity.getUsername())) {
            ql.append(" and u.username=:username");
            params.put("username", entity.getUsername());
        }
        if (StringUtils.isNotEmpty(entity.getName())) {
            ql.append(" and u.name=:name");
            params.put("name", entity.getName());
        }
        if (StringUtils.isNotEmpty(entity.getUserType())) {
            ql.append(" and u.userType=:userType");
            params.put("userType", entity.getUserType());
        }
        if (StringUtils.isNotEmpty(entity.getPhone())) {
            ql.append(" and u.phone=:phone");
            params.put("phone", entity.getPhone());
        }

        if (entity.getOrgId() != null) {
            ql.append(" and u.orgId=:orgId");
            params.put("orgId", entity.getOrgId());
        }
        if (StringUtils.isNotEmpty(entity.getSex())) {
            ql.append(" and u.sex=:sex");
            params.put("sex", entity.getSex());
        }
        if (StringUtils.isNotEmpty(entity.getRoleCode())) {
            ql.append(" and r.code=:code");
            params.put("code", entity.getRoleCode());
        }
        if (entity.getRegionCode() != null) {
            ql.append(" and u.regionCode=:regionCode");
            params.put("regionCode", entity.getRegionCode());
        } else {
            // 查询自己机构下的用户
            ql.append(" and region.gradeCode like :gradeCode");
            params.put("gradeCode", UserUtils.getUser().getRegionGradeCode() + "%");
        }

        ql.append(" and u.delFlag='0' group by ur.userId ");
        return ql.toString();
    }

    /**
     * @说明:分页查询
     * @开发: liuyw
     * @时间: 2019年2月26日
     * @参数:@param page
     * @参数:@param entity
     * @参数:@return
     */
    public Page<User> findPage(Page<User> page, User entity) {
        Map<String, Object> params = new HashMap<>(2);
        String ql = findHQL(entity, params);
        return this.userDao.findPage(page, ql, params);
    }

    /**
     * 根据角色查询用户
     *
     * @param userId
     * @return
     */
    public List<Long> findRoleByUserId(Long userId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userId", userId);
        StringBuilder sql = new StringBuilder("select role_id id from  sys_user_role a where user_id=:userId ");
        List<Map<String, Object>> list = userDao.nativeQuery(sql.toString(), params);
        List<Long> result = new ArrayList<>();
        for (Map<String, Object> m : list) {
            result.add(Long.valueOf(m.get("id").toString()));
        }

        return result;
    }

    /**
     * 根据登入账号 查询用户信息
     *
     * @param loginName
     * @return
     */
    public LoginUser findByLoginName(String loginName) {
        Map<String, Object> params = new HashMap<>();
        params.put("loginName", loginName);
        StringBuilder loginSql = new StringBuilder(
                "select  _user.id,_user.username,_user.password \"password\",_user.name,_user.rank_code \"rankCode\",");
        loginSql.append(
                "region.grade_code \"regionGradeCode\",region.region_code \"regionCode\",region.region_name \"regionName\",");
        loginSql.append(
                "org.id \"orgId\",org.org_code \"orgCode\",org.org_name \"orgName\",org.grade_code \"orgGradeCode\"  ");
        loginSql.append("from sys_user _user ");
        loginSql.append("left join sys_region_city region on region.region_code=_user.region_code ");
        loginSql.append("left join sys_org org on org.id=_user.org_id ");
        loginSql.append(
                "where  _user.del_flag='0' and (_user.username=:loginName or _user.phone=:loginName or _user.ding_user_id = :loginName  or _user.email = :loginName) ");

        return userDao.gsonEntity(loginSql.toString(), params, LoginUser.class);
    }

    /**
     * 查询列表
     *
     * @param entity
     * @return
     */
    public List<User> findList(User entity) {
        Map<String, Object> params = new HashMap<>();
        String ql = findHQL(entity, params);
        return this.userDao.findList(ql, params);
    }

}
